Return to start page

Core/Maths/Library Unit.j

Code

		
1			library ALibraryCoreMathsUnit requires ALibraryCoreGeneralUnit, ALibraryCoreMathsHandle, ALibraryCoreMathsPoint
2
3 /// Die Entfernung zwischen zwei Einheiten.
4 /// Da es die nativen Funktionen GetUnitX() und GetUnitY() gibt, dürfte es schneller sein, als erst Locations der Einheiten zu erzeugen und diese zu vergleichen.
5 /// Achtung: Nur verwenden, wenn man auch wirklich den Z-Wert braucht.
6 /// @return Returns the distance between units.
7 function GetDistanceBetweenUnitsWithZ takes unit unit0, unit unit1 returns real
8 local location unitLocation0 = GetUnitLoc(unit0)
9 local location unitLocation1 = GetUnitLoc(unit1)
10 local real distance = GetDistanceBetweenUnits(unit0, unit1, GetLocationZ(unitLocation0), GetLocationZ(unitLocation1)) //ALibraryMathsHandle
11 call RemoveLocation(unitLocation0)
12 set unitLocation0 = null
13 call RemoveLocation(unitLocation1)
14 set unitLocation1 = null
15 return distance
16 endfunction
17
18 /// Does not create any locations.
19 function SetUnitPolarProjectionPosition takes unit usedUnit, real angle, real distance returns nothing
20 local real x = GetUnitPolarProjectionX(usedUnit, angle, distance)
21 local real y = GetUnitPolarProjectionY(usedUnit, angle, distance)
22 call SetUnitPosition(usedUnit, x, y)
23 call SetUnitFacing(usedUnit, angle)
24 endfunction
25
26 /// Makes a unit flyable by adding and removing the ability Crow Form.
27 /// Thus you can change its high.
28 function MakeUnitFlyable takes unit usedUnit returns nothing
29 if (GetUnitAbilityLevel(usedUnit, 'Amrf') == 0) then
30 call UnitAddAbility(usedUnit, 'Amrf')
31 call UnitRemoveAbility(usedUnit, 'Amrf')
32 endif
33 endfunction
34
35 /// Ändert die Höhe einer Einheit.
36 /// Die neue Höhe muss >= der Bodenhöhe an dem Punkt, an dem sich die Einheit befindet, sein.
37 /// @author WaterKnight
38 function SetUnitZ takes unit usedUnit, real z returns nothing
39 call MakeUnitFlyable(usedUnit)
40 call SetUnitFlyHeight(usedUnit, z - GetUnitZ(usedUnit), 0.0) //ALibraryMathsHandle
41 endfunction
42
43 /**
44 * Beschreibung: Die Funktionen setzen eine Einheit auf angegebene Koordinaten, falls die Einheit
45 * auf diesen stehen könnte. Dabei wird die Betrachtung für jede Koordinate separat ausgeführt.
46 * Das heißt, die Einheit könnte in eine Achsenrichtung bewegt werden, auch wenn sie es in die
47 * Zweite nicht kann. Dadurch slidet sie an Grenzen, wenn die Bewegung in eine Richtung möglich
48 * ist. Die Funktionen returnen, ob die Einheit erfolgreich an die gegebenen Koordinaten bewegt
49 * wurde.
50 * Hinweise: Um zu entscheiden, ob die Einheit geblockt wird, wird ein kleiner Toleranzbereich
51 * genommen. Auf Bewegung bezogene Ereignisse werden ausgeführt, auch wenn die Einheit im
52 * Endeffekt zurückgesetzt wurde. Sowohl das Prüfen als auch das Zurücksetzen der Position
53 * erfolgt über Bewegungsaktionen, die auf die Einheit angewandt werden. Da die Funktionen wohl
54 * im Zusammenhang mit rekursiven Fortbewegungssystemen einer Einheit gebraucht werden (die
55 * vorigen Koordinaten einer Einheit werden ausgelesen, um sie zum Beispiel für die Ermittlung
56 * der Nächsten zu verarbeiten), muss man bei allen drei Funktionen die alten
57 * Positionsinformationen der Einheit mitliefern. Das ist besser für die
58 * Schnelligkeitsperformance, als wenn man es mehrfach ausliest.
59 * @author WaterKnight
60 */
61 function SetUnitXIfNotBlocked takes unit usedUnit, real oldX, real oldY, real x returns boolean
62 call SetUnitPosition(usedUnit, x, oldY)
63 if ((RAbsBJ(GetUnitX(usedUnit) - x) > 1) or (RAbsBJ(GetUnitY(usedUnit) - oldY) > 1)) then
64 call SetUnitX(usedUnit, oldX)
65 call SetUnitY(usedUnit, oldY)
66 return false
67 endif
68 return true
69 endfunction
70
71 /// @author WaterKnight
72 function SetUnitYIfNotBlocked takes unit usedUnit, real oldX, real oldY, real y returns boolean
73 call SetUnitPosition(usedUnit, oldX, y)
74 if ((RAbsBJ(GetUnitX(usedUnit) - oldX) > 1) or (RAbsBJ(GetUnitY(usedUnit) - y) > 1)) then
75 call SetUnitX(usedUnit, oldX)
76 call SetUnitY(usedUnit, oldY)
77 return false
78 endif
79 return true
80 endfunction
81
82 /// @author WaterKnight
83 function SetUnitXYIfNotBlocked takes unit usedUnit, real oldX, real oldY, real x, real y returns boolean
84 if (SetUnitXIfNotBlocked(usedUnit, oldX, oldY, x)) then
85 if (SetUnitYIfNotBlocked(usedUnit, x, oldY, y )) then
86 return true
87 endif
88 else
89 call SetUnitYIfNotBlocked(usedUnit, oldX, oldY, y)
90 endif
91 return false
92 endfunction
93
94 /// @author Grater
95 /// @source http://www.wc3jass.com/
96 function FindClosestUnit takes group g, real x, real y returns unit
97 local real dx
98 local real dy
99 local group tempGroup
100 local real maxDist = 999999.0
101 local real dist
102 local unit u = null
103 local unit closest = null
104 if (bj_wantDestroyGroup == true) then
105 set tempGroup = g
106 else
107 set tempGroup = CreateGroup()
108 call GroupAddGroup(g, tempGroup)
109 endif
110 set bj_wantDestroyGroup = false
111
112 loop
113 set u = FirstOfGroupSave(tempGroup)
114 call GroupRemoveUnit(tempGroup, u)
115 exitwhen (u == null)
116 set dx = GetUnitX(u) - x
117 set dy = GetUnitY(u) - y
118 set dist = SquareRoot(dx*dx+dy*dy)
119 if (dist < maxDist) then
120 set closest = u
121 set maxDist = dist
122 endif
123 set u = null
124 endloop
125 call DestroyGroup(tempGroup)
126 set tempGroup = null
127 return closest
128 endfunction
129
130 /// @author Grater
131 /// @source http://www.wc3jass.com/
132 function FindClosestUnitByLocation takes group g, location loc returns unit
133 return FindClosestUnit(g, GetLocationX(loc), GetLocationY(loc))
134 endfunction
135
136 /// @author Tamino Dauth
137 function FindClosestUnitByRect takes group usedGroup, rect usedRect returns unit
138 return FindClosestUnit(usedGroup, GetRectCenterX(usedRect), GetRectCenterY(usedRect))
139 endfunction
140
141 /**
142 * IsUnitOnRect returns true if the unit's collision circle
143 * ------------ interesects with a rect.
144 *
145 * Useful for example, in a "enter rect" event
146 * it will return true, unlike blizz' RectContainsUnit
147 *
148 * probably slower than RectContainsUnit
149 * @author Vexorian
150 */
151 function IsUnitOnRect takes unit u, rect r returns boolean
152 local real x =GetUnitX(u)
153 local real y =GetUnitY(u)
154 local real mx = GetRectMaxX(r)
155 local real nx = GetRectMinX(r)
156 local real my = GetRectMaxY(r)
157 local real ny = GetRectMinY(r)
158 if (nx <= x) and (x <= mx) and (ny <= y) and (y <= my) then
159 return true
160 endif
161 if(x>mx) then
162 set x=mx
163 elseif(x
164
set x=nx
165 endif
166 if(y>my) then
167 set y=my
168 elseif(y
169
set y=ny
170 endif
171 return IsUnitInRangeXY(u,x,y,0.0)
172 endfunction
173
174 /// @author Tamino Dauth
175 function SetUnitFacingToFaceRectTimed takes unit whichUnit, rect whichRect, real duration returns nothing
176 call SetUnitFacingTimed(whichUnit, GetAngleBetweenPoints(GetUnitX(whichUnit), GetUnitY(whichUnit), GetRectCenterX(whichRect), GetRectCenterY(whichRect)), duration)
177 endfunction
178
179 /// @author Tamino Dauth
180 function SetUnitToRandomPointOnRect takes unit whichUnit, rect whichRect returns nothing
181 local real minX = RMinBJ(GetRectMinX(whichRect), GetRectMaxX(whichRect))
182 local real maxX = RMaxBJ(GetRectMinX(whichRect), GetRectMaxX(whichRect))
183 local real minY = RMinBJ(GetRectMinY(whichRect), GetRectMaxY(whichRect))
184 local real maxY = RMaxBJ(GetRectMinY(whichRect), GetRectMaxY(whichRect))
185 call SetUnitX(whichUnit, GetRandomReal(minX, maxX))
186 call SetUnitY(whichUnit, GetRandomReal(minY, maxY))
187 endfunction
188
189 endlibrary